#include "MenuState.h"
#include "..\Managers\StateManager.h"
#include "..\Managers\RenderManager.h"
#include "..\Engines\RenderEngine.h"
#include "..\Define.h"
#include "..\Managers\PhysicsManager.h"
#include "..\Managers\InputManager.h"
#include "..\Managers\MenuManager.h"
#include "..\Define.h"
#include "..\GUI\TextButton.h"
#include "..\Graphics\BlinkingText.h"
#include "..\Managers\ResourceManager.h"
#include "..\Managers\EventManager.h"
#include "..\Graphics\CloudSpawner.h"
#include "PlayState.h"
#include "..\Graphics\RectangleShape.h"

#include <iostream>

MenuState::MenuState(){}

MenuState::~MenuState(){}

void MenuState::initialize()
{
	m_loadGame = false;
	m_menuPosition = MENU_NONE;
	m_fadeLogo = false;
	m_skipIntro = false;
	m_startGame = false;
	m_eventManager = new EventManager;

	const float skyscraperPos = 370.0f;
	const float btnScale = 0.3f;
	const int skyscraperHeight = 4;

	m_camera = RenderManager::getSingleton().getRenderEngine()->createCamera(1, "main");
	m_camera->setVelocity(1.0f);
	m_camera->setPosition(VSW_05, VSH_05);

	m_sprite = RenderManager::getSingleton().getRenderEngine()->createSprite(1, "rockman_main", 1.6f);
	m_sprite->setTextureRect(0, 7 * 42, 42, 42);
	m_sprite->setScale(-1.0f, 1.0f);
	m_moon = RenderManager::getSingleton().getRenderEngine()->createSprite(1, "moon", 0.9f);
	m_moon->setPosition(skyscraperPos + 80.0f, -50.0f);
	m_moon->setScale(1.5f, 1.5f);

	m_animation = new vn::AnimationManager(m_sprite);
	m_animation->loadAnimations("animations/rockman_menu.xml");
	m_animation->setAnimation("wind");
	m_animation->setNextAnimation("helmet", "disappear");
	m_animation->setNextAnimation("disappear", "line");

	m_logo = RenderManager::getSingleton().getRenderEngine()->createSprite(2, "mm_logo", 1.5f);
	m_logo->setPosition(150.0f, 70.0f);
	m_logo->setDoRender(false);
	vn::IntRect rect = m_logo->getTextureRect();
	m_logo->setTextureRect(rect.x, rect.y, rect.w, 0);
	vn::IntRect l_rect = m_logo->getTextureRect();
	m_logo_height = static_cast<float>(l_rect.h);

	vn::TileEngine* tiles = nullptr;
	float oldX = 0.0f;
	for (int i = 0; i < 4; i++)
	{
		tiles = RenderManager::getSingleton().getRenderEngine()->createTiles(1, "levels/city_view.xml", 0.0f);
		tiles->setPosition(vn::Vector2(oldX, 0.0f));
		oldX += tiles->getDimension().w;
	}

	
	float maxHeight = 0.0f;
	float oldY = 0.0f;
	for (int i = 0; i < skyscraperHeight; i++)
	{
		tiles = RenderManager::getSingleton().getRenderEngine()->createTiles(1, "levels/skyscraper.xml", 1.4f);
		tiles->setPosition(vn::Vector2(skyscraperPos, oldY));
		oldY -= tiles->getDimension().h;
		maxHeight -= tiles->getDimension().h;
	}
	float height = tiles->getDimension().h;
	
	tiles = RenderManager::getSingleton().getRenderEngine()->createTiles(1, "levels/skyscraper_top.xml", 1.4f);
	tiles->setPosition(vn::Vector2(skyscraperPos, maxHeight));

	float test = skyscraperHeight * height;

	m_sprite->setPosition(skyscraperPos + 45.0f, (height * skyscraperHeight) - VSH - (m_sprite->getTextureRect().h * 0.5f) - 42.0f);
	m_loop = ResourceManager::getSingleton().getAudioEngine()->loadMusic("music/mm_menu02.ogg");
	m_loop->setLoop(true);

	m_menuManager = new MenuManager(vn::Vector2(150.0f, 120.0f), 15.0f);
	
	std::function<void()> func = [this] { startGame(); };
	TextButton* button = new TextButton("Start Game", "mm_font", vn::Color::white, vn::Color::yellow, 2);
	button->registerFunctionCallback(func);
	button->setScale(btnScale);
	m_menuManager->addChoice(button);
	button = new TextButton("Load Game", "mm_font", vn::Color::white, vn::Color::yellow, 2);
	func = [this] { loadGame(); };
	button->setScale(btnScale);
	button->registerFunctionCallback(func);
	m_menuManager->addChoice(button);
	button = new TextButton("Options", "mm_font", vn::Color::white, vn::Color::yellow, 2);
	button->setScale(btnScale);
	m_menuManager->addChoice(button);
	button = new TextButton("Quit", "mm_font", vn::Color::white, vn::Color::yellow, 2);
	button->setScale(btnScale);
	func = [this] { m_menuManager->setActive(false); m_quit->setActive(true); m_menuPosition = MENU_QUIT; };
	button->registerFunctionCallback(func);
	m_menuManager->addChoice(button);
	m_menuManager->setCurrentChoice(0);
	m_menuManager->setActive(false);

	m_quit = new MenuManager(vn::Vector2(150.0f, 130.0f), 15.0f);

	func = [this] { StateManager::getSingleton().shutdown(); };
	button = new TextButton("Yes", "mm_font", vn::Color::white, vn::Color::yellow, 2);
	button->setScale(btnScale);
	button->registerFunctionCallback(func);
	m_quit->addChoice(button);

	func = [this] { m_menuManager->setActive(true); m_quit->setActive(false); m_menuPosition = MENU_MAIN; };
	button = new TextButton("No", "mm_font", vn::Color::white, vn::Color::yellow, 2);
	button->setScale(btnScale);
	button->registerFunctionCallback(func);
	m_quit->addChoice(button);
	m_quit->setCurrentChoice(1);
	m_quit->addTitle(2, "Are you sure?", "mm_font", vn::Color::white, btnScale, 1.0f);
	m_quit->setActive(false);


	m_credits = new MenuManager(vn::Vector2(150.0f, 120.0f), 15.0f);
	func = [this] { showCredits(); m_menuPosition = MENU_MAIN; };
	button = new TextButton("P", "mm_font", vn::Color::invisible, vn::Color::invisible);
	button->registerFunctionCallback(func);
	m_credits->addChoice(button);
	m_credits->setActive(false);
	m_credits->setCurrentChoice(0);

	m_pressStart = new BlinkingText(2, "Press Space", "mm_font", 2.0f);
	m_pressStart->setScale(btnScale);
	m_pressStart->setFadeStrength(500.0f);
	m_pressStart->setPosition(150.0f, 130.0f);
	m_pressStart->setActive(false);

	func = [this] { m_camera->setTarget(vn::Vector2(VSW_05, VSH_05 - 130.0f)); m_loop->play(); };
	m_eventManager->addEvent(new vn::Event(func, 1.0f));
	func = [this] { m_fadeLogo = true; m_logo->setDoRender(true);};
	m_eventManager->addEvent(new vn::Event(func, 5.0f));
	func = [this] { m_pressStart->setActive(true); };
	m_eventManager->addEvent(new vn::Event(func, 6.0f));

	m_cloudSpawner = new CloudSpawner(vn::IntRect(0, -100, static_cast<int>(VSW), static_cast<int>(VSH)), 200.0f, 200, 400, 1, 1.0f);
	m_cloudSpawner->addSpriteID("cloud01");
	m_cloudSpawner->addSpriteID("cloud02");
}

void MenuState::shutdown()
{
	delete m_animation;
	m_animation = nullptr;
	delete m_loop;
	m_loop = nullptr;
	delete m_cloudSpawner;
	m_cloudSpawner = nullptr;
	delete m_eventManager;
	m_eventManager = nullptr;
	delete m_pressStart;
	m_pressStart = nullptr;
	delete m_credits;
	m_credits = nullptr;
	delete m_quit;
	m_quit = nullptr;
	delete m_menuManager;
	m_menuManager = nullptr;
	RenderManager::getSingleton().getRenderEngine()->clearAll();
}

void MenuState::handleEvents()
{

}

void MenuState::update(const GameTime& p_gameTime)
{
	m_eventManager->update(p_gameTime);
	m_pressStart->update(p_gameTime);
	m_animation->update(p_gameTime);
	m_cloudSpawner->update(p_gameTime);

	switch(m_menuPosition)
	{
	case MENU_MAIN:
		m_menuManager->update();
		break;
	case MENU_CREDITS:
		m_credits->update();
		break;
	case MENU_QUIT:
		m_quit->update();
		break;
	default:
		break;
	}

	if (!m_skipIntro && InputManager::getSingleton().isKeyPressed("jump"))
	{
		m_menuPosition = MENU_MAIN;
		m_skipIntro = true;
		m_eventManager->clearEvents();
		m_menuManager->setActive(true);
		m_pressStart->setActive(false);
		m_logo->setTextureRect(0,0,256,64);
		m_logo->setDoRender(true);
		m_camera->setPosition(vn::Vector2(VSW_05, VSH_05 - 130.0f));
		m_fadeLogo = false;
	}

	if (m_fadeLogo)
		logoFade(p_gameTime);

	if (m_startGame)
	{
		if (m_animation->getCurrentID() == "line")
		{
			m_sprite->translate(0.0f, -(300.0f * p_gameTime.deltaTime()));
			if (m_sprite->getPosition().y < -190.0f)
				StateManager::getSingleton().setState(new PlayState(m_loadGame));
		}
	}

}

inline void MenuState::logoFade(const GameTime& p_gameTime)
{
	vn::IntRect rect = m_logo->getTextureRect();
	m_logo_height = std::min(m_logo_height + (80.0f * p_gameTime.deltaTime()), 64.0f);

	m_logo->setTextureRect(rect.x, rect.y, rect.w, static_cast<int>(m_logo_height));
	if (m_logo_height >= 64.0f)
		m_fadeLogo = false;
}

void MenuState::showCredits()
{
	bool value = m_menuManager->isActive();
	m_menuManager->setActive(!value);
	m_credits->setActive(!m_credits->isActive());
}

void MenuState::startGame()
{
	if (m_startGame == false)
	{
		m_animation->setAnimation("helmet");
		m_startGame = true;
		m_menuManager->setActive(false);
	}
}

void MenuState::loadGame()
{
	if (m_startGame == false)
	{
		m_animation->setAnimation("helmet");
		m_startGame = true;
		m_loadGame = true;
		m_menuManager->setActive(false);
	}
}
